home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld Secrets (4th Edition)
/
Mac Secrets CD 4th Ed.toast
/
Apple Advanced Technologies
/
Apple Speech Technologies 1.5
/
PlainTalk Developer Info
/
Speech Recognition Manager SDK
/
SR Sample Code
/
Speakable Items Example
/
Sources
/
Process & Finder Stuff
/
ProcessUtils.c
< prev
next >
Wrap
Text File
|
1995-06-07
|
10KB
|
308 lines
/*****************************************************************************
*
* ProcessUtils.c
*
* DESCRIPTION
* Utiltiy routines for finding and manipulating processes.
*
* AUTHOR: Matt Pallakoff
*
* CREATED: 9-9-91
*
*****************************************************************************/
#include "ProcessUtils.h"
OSErr PUFindApp (ResType signature, FSSpec *aFSSpec);
OSErr PULaunchApp (FSSpec *aFSSpec);
OSErr PULaunchAppWithSignature (ResType serviceSignature);
void ClearEvenSizeBlock(void *loc, Size len);
/****************************************************************************/
void ClearEvenSizeBlock(void *loc, Size len)
{
short *sPtr = loc;
short sz = len>>1;
for (sz = (len>>1)-1; sz >= 0; sz--);
*sPtr++ = 0;
}
/****************************************************************************/
OSErr PUFindApp (ResType signature, FSSpec *aFSSpec)
{
DTPBRec aDTPBRec;
short dtRefNum, volRefNum;
OSErr err, err2, volErr;
short i;
Str255 name;
HParamBlockRec volPB;
err = -1; /* representing 'not found' */
/* For each mounted volume... */
i = 0;
volErr = noErr;
while ((volErr == noErr) && (err != noErr)) {
++i;
/* Get Volume information. */
volPB.ioParam.ioCompletion = nil;
volPB.ioParam.ioNamePtr = name;
volPB.volumeParam.ioVolIndex = i;
volErr = PBHGetVInfo(&volPB, false);
if (!volErr) {
volRefNum = volPB.volumeParam.ioVRefNum;
aDTPBRec.ioNamePtr = name;
aDTPBRec.ioVRefNum = volRefNum;
/* Get Desktop File Database reference for the volume. */
err2 = PBDTGetPath(&aDTPBRec);
if (!err2) {
dtRefNum = aDTPBRec.ioDTRefNum;
aDTPBRec.ioCompletion = nil;
aDTPBRec.ioNamePtr = name;
aDTPBRec.ioDTRefNum = dtRefNum;
aDTPBRec.ioIndex = 0; /* Find most recent. */
aDTPBRec.ioFileCreator = signature;
err = PBDTGetAPPL(&aDTPBRec, false); /* Search the desktop database for the application. */
/* If found, return FSSpec specifying where it is. */
if (!err)
err = FSMakeFSSpec(volRefNum,aDTPBRec.ioAPPLParID,aDTPBRec.ioNamePtr,aFSSpec);
}
}
} /* while */
return err;
}
/****************************************************************************/
/*
* PULaunchApp launches the application corresponding to the given fsspec.
*/
OSErr PULaunchApp (FSSpec *aFSSpec)
{
OSErr err;
LaunchParamBlockRec myLaunchParams;
myLaunchParams.launchBlockID = extendedBlock;
myLaunchParams.launchEPBLength = extendedBlockLen;
myLaunchParams.launchFileFlags = 0;
myLaunchParams.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch;
myLaunchParams.launchAppSpec = aFSSpec;
myLaunchParams.launchAppParameters = nil;
err = LaunchApplication(&myLaunchParams);
return err;
}
/****************************************************************************/
/* PULaunchAppWithSignature looks for an application with the given signature
* on a mounted volume and if it finds it tries to launch it. If all goes well,
* noErr is returned. If the app couldn't be found or launched then a non-noErr
* value is returned.
*/
OSErr PULaunchAppWithSignature (ResType serviceSignature)
{
FSSpec aFSSpec;
OSErr err;
err = PUFindApp(serviceSignature, &aFSSpec);
if (!err)
err = PULaunchApp(&aFSSpec);
return err;
}
/****************************************************************************/
OSErr PUFindLocalProcess (OSType processSignature,
Boolean launchIfCan,
LocationNameRec *theLocation,
PortInfoRec *thePortInfo)
{
PPCPortRec myPortName;
PortInfoRec myPortInfo;
Boolean found = false;
short index = 0;
IPCListPortsPBPtr thePB = (IPCListPortsPBPtr)NewPtrClear(sizeof(IPCListPortsPBRec));
OSErr err = MemError();
/* Exit immedieately if couldn't allocte param block. */
if (err)
return err;
/* Check local machine for process with given signature. */
/* Match any port. We could match just ports with given signature and a given type,
* but then we'd either have to assume the system always gives applications a type
* of 'ep10' (which might not be true in the future) or we'd have to have services
* explicitly open their ports using PPCOpenPort, providing their type (which will
* usually by 'APPL'. It's easier just to look through all available local ports, looking
* for a port with creator equal to the processSignature we're looking for.
* We could also use the serviceName to determine the port, but then if we decided to
* change the name of a service (e.g. "DECTalk Service" to "Talker Server") then
* we'd have to recompile E.T. One is much less likely to change the services type.
*/
while ((!err) && (!found)) {
myPortName.nameScript = 0;
myPortName.name[1] = '=';
myPortName.name[0] = 1;
myPortName.portKindSelector = ppcByString;
myPortName.u.portTypeStr[1] = '=';
myPortName.u.portTypeStr[0] = 1;
thePB->ioCompletion = nil;
thePB->startIndex = index;
thePB->requestCount = 1;
thePB->portName = &myPortName;
thePB->locationName = nil;
thePB->bufferPtr = &myPortInfo;
err = IPCListPorts(thePB, FALSE);
if (!err)
if (thePB->actualCount <= 0)
err = PROCESS_NOT_FOUND_ERR; /* Return PROCESS_NOT_FOUND_ERR if port not found. */
else
found = (((myPortName.portKindSelector == ppcByCreatorAndType) && (myPortInfo.name.u.port.portCreator == processSignature)) ||
((myPortName.portKindSelector == ppcByString) && (*(OSType *)(myPortInfo.name.u.portTypeStr + 1) == processSignature)));
++index;
}
/* Cleanup. */
DisposPtr((Ptr)thePB);
/* If we found the correct service process, return its location and name. */
if (found) {
ClearEvenSizeBlock(theLocation, sizeof(LocationNameRec)); /* Clear location means local machine. */
BlockMove((Ptr)&myPortInfo, (Ptr)thePortInfo, sizeof(PortInfoRec));
err = noErr;
}
/* Couldn't find running process. See if can find app on mounted volume and launch it. */
if ((!found) && (launchIfCan)) {
/* Try to launch application. */
err = PULaunchAppWithSignature(processSignature);
/* Call PUFindLocalProcess again to get location of newly launched app. */
if (!err)
err = PUFindLocalProcess(processSignature, false, theLocation, thePortInfo);
found = (!err);
}
return err;
}
/*****************************************************************************************/
OSErr PUSendAppleEventWith2Params(long sessionID,
OSType signature,
LocationNameRec *theLocation,
PortInfoRec *thePortInfo,
AEEventClass eventClass,
AEEventID eventID,
AEKeyword keyWord1,
DescType dataType1,
void *dataPtr1,
Size dataSize1,
AEKeyword keyWord2,
DescType dataType2,
void *dataPtr2,
Size dataSize2,
Boolean waitForReply,
long timeOut,
AppleEvent *theReply)
{
OSErr err,err2;
TargetID theTargetID;
AppleEvent theAevt;
AEAddressDesc theTarget;
AESendMode sendMode;
if (sessionID != 0) {
err = AECreateDesc(typeSessionID, (Ptr) &sessionID, (Size)sizeof(sessionID), &theTarget);
} else if ((long)signature != 0) {
err = AECreateDesc(typeApplSignature, (Ptr) &signature, (Size)sizeof(signature), &theTarget);
} else {
theTargetID.location = *theLocation;
theTargetID.name = thePortInfo->name;
err = AECreateDesc(typeTargetID, (Ptr) &theTargetID, (Size)sizeof(theTargetID), &theTarget);
}
if (err == noErr)
err = AECreateAppleEvent(eventClass, eventID, &theTarget, kAutoGenerateReturnID, kAnyTransactionID, &theAevt);
if ((err == noErr) && (dataPtr1 != 0))
err = AEPutParamPtr(&theAevt, keyWord1, dataType1, (Ptr) dataPtr1, dataSize1);
if ((err == noErr) && (dataPtr2 != 0))
err = AEPutParamPtr(&theAevt, keyWord2, dataType2, (Ptr) dataPtr2, dataSize2);
if (waitForReply)
sendMode = kAEWaitReply;
else
sendMode = kAENoReply;
if (err == noErr)
err = AESend(&theAevt, theReply, sendMode, kAENormalPriority, timeOut, (AEIdleUPP)0, (AEFilterUPP)0);
/* Get rid of structures */
err2 = AEDisposeDesc(&theAevt);
err2 = AEDisposeDesc(&theTarget);
return(err);
}
/*****************************************************************************************/
OSErr PUSendAppleEventWith1Param(LocationNameRec *theLocation,
PortInfoRec *thePortInfo,
AEEventClass eventClass,
AEEventID eventID,
DescType dataType,
void *dataPtr,
Size dataSize)
{
return PUSendAppleEventWith2Params(0, (OSType)0, theLocation, thePortInfo, eventClass, eventID,
keyDirectObject, dataType, dataPtr, dataSize, keyDirectObject, (DescType)0,nil,(Size)0,
false, 0, NULL);
}
/*****************************************************************************************/
OSErr PUSendAppleEventWith1ParamAndWait(LocationNameRec *theLocation,
PortInfoRec *thePortInfo,
AEEventClass eventClass,
AEEventID eventID,
DescType dataType,
void *dataPtr,
Size dataSize,
long timeout,
AppleEvent *theReply)
{
return PUSendAppleEventWith2Params(0, (OSType)0, theLocation, thePortInfo, eventClass, eventID,
keyDirectObject, dataType, dataPtr, dataSize, keyDirectObject, (DescType)0,nil,(Size)0,
true, timeout, theReply);
}
/*****************************************************************************************/